<?php
class Bookmarkable extends Doctrine_Template
{

  /**
   * Template options
   *
   * @var array $_options
   */
  protected $_options = array(
    'owner_component' => 'User',
    //these options are just for caching purposes
    'owner_id' => array('local' => '', 'foreign' => ''),
    'component_id' => array('local' => '', 'foreign' => ''),
  );

  public function __construct(array $options = array())
  {
    $this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options);
    $this->_options['owner_table'] = Doctrine::getTable($this->_options['owner_component']);

    $this->_plugin = new Doctrine_Bookmark($this->_options);
  }

  /**
   * Initialize the Ratable plugin for the template
   *
   * @return void
   */
  public function setUp()
  {
    if ($this->getTable()->isIdentifierComposite())
    {
      throw new Doctrine_Exception('Composite identifiers are not supported yet');
    }

    $ids = array('related' => $this->getTable()->getIdentifier(),
      'owner' => $this->_options['owner_table']->getIdentifier());
    $this->_options['component_id'] = array('foreign' => Doctrine_Inflector::tableize($this->getTable()->getComponentName() . '_' . $ids['related']),
      'local' => $ids['related']);
    $this->_options['owner_id'] = array('foreign' => Doctrine_Inflector::tableize($this->_options['owner_table']->getComponentName() . '_' . $ids['owner']),
      'local' => $ids['owner']);

    $this->_plugin->setOption('component_id', $this->_options['component_id']);
    $this->_plugin->setOption('owner_id', $this->_options['owner_id']);

    $this->_plugin->initialize($this->_table);
  }
  
  public function toogleBookmarkBy($user_id)
  {
    if (!$this->isBookmarkedBy($user_id))
    {
      $result = $this->bookmarkBy($user_id);
      return (array('mode' => 'add', 'success' => $result));
    }
    else
    {
      $result = $this->removeBookmarkFrom($user_id);
      return (array('mode' => 'remove', 'success' => $result));
    }

  }//toogle bookmark

  /**
   * Bookmarks an entity by specified user
   *
   * @param int $user_id
   */
  public function bookmarkBy($user_id)
  {
    if (!$this->isBookmarkedBy($user_id))
    {
      $cname = $this->getPlugin()->getTable()->getComponentName();
      $bkmrk = new $cname;
      $data = array(
        $this->_options['component_id']['foreign'] => $this->getInvoker()->id,
        $this->_options['owner_id']['foreign'] => $user_id,
      );
      $bkmrk->fromArray($data);

      $bkmrk->save();

      return true;
    }
    return false;
  }

  /**
   * Checks whether specified user was bookmarked this object
   *
   * @param int $user_id
   * @return boolean 
   */
  public function isBookmarkedBy($user_id)
  {
    return $this->getBookmarksQuery()->
      andWhere('b.' . $this->_options['owner_id']['foreign'] . ' = ?', $user_id)->
      count() > 0;
  }

  /**
   * Removes a bookmark from user
   *
   * @param int $user_id
   */
  public function removeBookmarkFrom($user_id)
  {
    return $this->getBookmarksQuery()->
      delete()->
      andWhere('b.' . $this->_options['owner_id']['foreign'] . ' = ?', $user_id)->
      execute();
  }

  public function clearBookmarks()
  {
    return $this->getBookmarksQuery()->
      delete()->
      execute();
  }

  public function countBookmarks()
  {
    return $this->getBookmarksQuery()->count();
  }

  /**
   * Returns bookmarks query draft
   *
   * @return Doctrine_Query
   */
  public function getBookmarksQuery($alias = 'b')
  {
    return Doctrine_Query::create()
      ->from($this->getPlugin()->getTable()->getComponentName() . ' as ' . $alias)
      ->where($alias . '.' . $this->_options['component_id']['foreign'] . ' = ?', array($this->getInvoker()->id));
  }
}